package com.hskn.hss.module.othercarcsotCfg.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hskn.hss.core.annotation.DataScope;
import com.hskn.hss.core.domain.BaseEntity;
import com.hskn.hss.core.utils.LoginUtils;
import com.hskn.hss.entity.AjaxResult;
import com.hskn.hss.exception.ExcelReaderDataException;
import com.hskn.hss.exception.HssException;
import com.hskn.hss.module.costdict.service.ICostDictService;
import com.hskn.hss.module.costdictitem.entity.CostDictItem;
import com.hskn.hss.module.costdictitem.mapper.CostDictItemMapper;
import com.hskn.hss.module.depart.entity.SysDepart;
import com.hskn.hss.module.depart.mapper.SysDepartMapper;
import com.hskn.hss.module.depart.service.ISysDepartService;
import com.hskn.hss.module.othercarcsotCfg.entity.TlOthercarcostCfg;
import com.hskn.hss.module.othercarcsotCfg.mapper.TlOthercarcostCfgMapper;
import com.hskn.hss.module.othercarcsotCfg.service.ITlOthercarcostCfgService;
import com.hskn.hss.module.othercarcsotCfg.to.OtherCarCostCfgListTO;
import com.hskn.hss.module.tlcar.entity.TlCar;
import com.hskn.hss.module.tlcar.mapper.TlCarMapper;
import com.hskn.hss.module.tlcar.service.ITlCarService;
import com.hskn.hss.module.tlcartype.entity.TlCarType;
import com.hskn.hss.module.tlcartype.service.ITlCarTypeService;
import com.hskn.hss.module.user.entity.User;
import com.hskn.hss.module.user.mapper.UserMapper;
import com.hskn.hss.module.user.service.IUserService;
import com.hskn.hss.module.userdepart.entity.SysUserDepart;
import com.hskn.hss.module.userdepart.mapper.SysUserDepartMapper;
import com.hskn.hss.to.ForIdsTO;
import com.hskn.hss.utils.AttributeUtils;
import com.hskn.hss.utils.GroupingByUtils;
import com.hskn.hss.utils.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2021-05-06
 */
@Service
public class TlOthercarcostCfgServiceImpl extends ServiceImpl<TlOthercarcostCfgMapper, TlOthercarcostCfg> implements ITlOthercarcostCfgService {

    @Resource
    TlOthercarcostCfgMapper TlOthercarcostCfgMapper;
    @Resource
    SysUserDepartMapper sysUserDepartMapper;
    @Resource
    IUserService userService;
    @Resource
    ISysDepartService departService;
    @Resource
    ITlCarService carService;
    @Resource
    ITlCarTypeService carTypeService;
    @Resource
    UserMapper userMapper;
    @Resource
    ICostDictService costDictService;
    @Resource
    CostDictItemMapper costDictItemMapper;
    @Resource
    private SysDepartMapper departMapper;
    @Resource
    private TlCarMapper carMapper;

    @Override
    public AjaxResult insert(JSONObject params) {

        String uid = LoginUtils.getUser().getUid();
        TlOthercarcostCfg tlOthercarcostCfg = params.getObject("data", TlOthercarcostCfg.class);
        QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUserDepart::getUserid, uid);
        String deptid = sysUserDepartMapper.selectOne(queryWrapper).getDepid();
        Map<String, TlCar> carMap = carService.getCarMap(new QueryWrapper<>());
        if (carMap != null && carMap.containsKey(tlOthercarcostCfg.getCarnumid())) {
            tlOthercarcostCfg.setCartype(carMap.get(tlOthercarcostCfg.getCarnumid()).getCartypeid());
            tlOthercarcostCfg.setDriverid(carMap.get(tlOthercarcostCfg.getCarnumid()).getBindaccount());

        }
        tlOthercarcostCfg.setId(StringUtils.uuid());
        tlOthercarcostCfg.setCreatby(uid);
        tlOthercarcostCfg.setCreattime(new Date());
        tlOthercarcostCfg.setDeptid(deptid);

        int i = TlOthercarcostCfgMapper.insert(tlOthercarcostCfg);
        boolean flag = i > 0;

        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public AjaxResult update(JSONObject params) {

        String uid = LoginUtils.getUser().getUid();
        TlOthercarcostCfg tlOthercarcostCfg = params.getObject("data", TlOthercarcostCfg.class);
        tlOthercarcostCfg.setUpdateby(uid);
        tlOthercarcostCfg.setUpdatetime(new Date());
        Map<String, TlCar> carMap = carService.getCarMap(new QueryWrapper<>());
        if (carMap != null && carMap.containsKey(tlOthercarcostCfg.getCarnumid())) {
            tlOthercarcostCfg.setCartype(carMap.get(tlOthercarcostCfg.getCarnumid()).getCartypeid());
            tlOthercarcostCfg.setDriverid(carMap.get(tlOthercarcostCfg.getCarnumid()).getBindaccount());

        }
        int i = TlOthercarcostCfgMapper.updateById(tlOthercarcostCfg);

        boolean flag = i > 0;

        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public AjaxResult deleteByid(ForIdsTO forIdsTO) {
        try {
            TlOthercarcostCfgMapper.deleteBatchIds(forIdsTO.getIds());
            return AjaxResult.success("操作成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("报错ERROR", e);
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public TlOthercarcostCfg getitemByid(String id) throws HssException {
        QueryWrapper<TlOthercarcostCfg> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TlOthercarcostCfg::getId, id);
        TlOthercarcostCfg tlOthercarcostCfg = TlOthercarcostCfgMapper.selectOne(queryWrapper);
        TlCar car = null;
        TlCarType carType = null;
        SysDepart depart = null;
        User user = null;
        CostDictItem costDictItem = null;
        if (tlOthercarcostCfg != null) {
            car = carService.getById(tlOthercarcostCfg.getCarnumid());
            depart = departService.getById(tlOthercarcostCfg.getDeptid());
            costDictItem = costDictItemMapper.selectById(tlOthercarcostCfg.getRepairreason());
        }
        if (car != null) {
            carType = carTypeService.getById(car.getCartypeid());
            user = userService.getById(car.getDriverid());
            tlOthercarcostCfg.setCarCardNum(car.getCarnumber());
        }
        if (carType != null) {
            tlOthercarcostCfg.setCarTyeName(carType.getTypename());
        }
        if (depart != null) {
            tlOthercarcostCfg.setDeptName(depart.getDepartName());
        }
        if (user != null) {
            tlOthercarcostCfg.setDriverName(user.getName());
        }
        if (costDictItem != null) {
            tlOthercarcostCfg.setRepairreasonName(costDictItem.getCostname());
        }
        return tlOthercarcostCfg;
    }

    @Override
    @DataScope(deptAlias = "deptidforcar", userAlias = "creatBy")
    public JSONObject getList(BaseEntity baseEntity, JSONObject params) throws HssException {
        Long page = StringUtils.isEmpty(params.getLong("page")) ? 1 : params.getLong("page");
        Long size = StringUtils.isEmpty(params.getLong("size")) ? 10 : params.getLong("size");
        JSONObject json = new JSONObject();

        Map map = new HashMap();
        map.put("deptIdForCar", params.getString("deptIdForCar"));
        map.put("carNumid", params.getString("carNumid"));
        map.put("costType", params.getString("costType"));
        map.put("startTime", AttributeUtils.timeCompletion(params.getString("startTime"), 's'));
        map.put("endTime", AttributeUtils.timeCompletion(params.getString("endTime"), 'e'));
        map.put("param", baseEntity.getParams());


        Page<TlOthercarcostCfg> othercarcostCfgPage = new Page<>(page, size, true);
        IPage<TlOthercarcostCfg> iPage = TlOthercarcostCfgMapper.listothercarcost(othercarcostCfgPage, map);
        json.put("total", iPage.getTotal());
        json.put("size", iPage.getSize());
        json.put("pages", iPage.getPages());
        json.put("current", iPage.getCurrent());
        json.put("othercarcostlist", iPage.getRecords());
        Map<String, User> userMap = userService.getUserMap();
        Map<String, TlCar> carMap = carService.getCarMap(new QueryWrapper<>());
        Map<String, SysDepart> departMap = departService.getDepartMap(new QueryWrapper<>());
        Map<String, TlCarType> carTypeMap = carTypeService.getCarTypeMap(new QueryWrapper<>());
        Map<String, CostDictItem> costDictItemMap = costDictService.getitemForCostDictItemMap(new QueryWrapper<>());

        List<TlOthercarcostCfg> list = othercarcostCfgPage.getRecords();
        for (TlOthercarcostCfg tlOthercarcostCfg : list) {
            if (carMap != null && carMap.containsKey(tlOthercarcostCfg.getCarnumid())) {
                tlOthercarcostCfg.setCarCardNum(carMap.get(tlOthercarcostCfg.getCarnumid()).getCarnumber());
            }
            if (userMap != null && userMap.containsKey(tlOthercarcostCfg.getDriverid())) {
                tlOthercarcostCfg.setDriverName(userMap.get(tlOthercarcostCfg.getDriverid()).getName());
            }
            if (carTypeMap != null && carTypeMap.containsKey(tlOthercarcostCfg.getCartype())) {
                tlOthercarcostCfg.setCarTyeName(carTypeMap.get(tlOthercarcostCfg.getCartype()).getTypename());
            }
            if (departMap != null && departMap.containsKey(tlOthercarcostCfg.getDeptid())) {
                tlOthercarcostCfg.setDeptName(departMap.get(tlOthercarcostCfg.getDeptid()).getDepartName());
            }

            if (costDictItemMap != null && costDictItemMap.containsKey(tlOthercarcostCfg.getRepairreason())) {
                tlOthercarcostCfg.setRepairreasonName(costDictItemMap.get(tlOthercarcostCfg.getRepairreason()).getCostname());
            }

        }
        return json;
    }

    @Override
    @DataScope(deptAlias = "deptidforcar", userAlias = "creatBy")
    public List<TlOthercarcostCfg> getTlOthercarcostCfgList(OtherCarCostCfgListTO otherCarCostCfgListTo, SimpleDateFormat format) throws ParseException {
        QueryWrapper<TlOthercarcostCfg> otherCarCostCfgQueryWrapper = new QueryWrapper<>();
        if (otherCarCostCfgListTo.getParams().containsKey("dataScope") && StringUtils.isNotEmpty(otherCarCostCfgListTo.getParams().get("dataScope").toString())) {
            otherCarCostCfgQueryWrapper.lambda().apply(otherCarCostCfgListTo.getParams().get("dataScope").toString());
        }
        if (StringUtils.isNotEmpty(otherCarCostCfgListTo.getDeptid())) {
            otherCarCostCfgQueryWrapper.lambda().eq(TlOthercarcostCfg::getDeptid, otherCarCostCfgListTo.getDeptid());
        }
        if (StringUtils.isNotEmpty(otherCarCostCfgListTo.getCarNumid())) {
            otherCarCostCfgQueryWrapper.lambda().eq(TlOthercarcostCfg::getCarnumid, otherCarCostCfgListTo.getCarNumid());
        }
        if (otherCarCostCfgListTo.getIds() != null && !otherCarCostCfgListTo.getIds().isEmpty()) {
            otherCarCostCfgQueryWrapper.lambda().in(TlOthercarcostCfg::getId, otherCarCostCfgListTo.getIds());
        }
        if (StringUtils.isNotEmpty(otherCarCostCfgListTo.getStartTime()) && StringUtils.isNotEmpty(otherCarCostCfgListTo.getEndTime())) {
            otherCarCostCfgQueryWrapper.lambda().ge(TlOthercarcostCfg::getCosttime, format.parse(otherCarCostCfgListTo.getStartTime()));
            otherCarCostCfgQueryWrapper.lambda().le(TlOthercarcostCfg::getCosttime, format.parse(otherCarCostCfgListTo.getEndTime()));
        }
        List<TlOthercarcostCfg> otherCarCostCfgList = TlOthercarcostCfgMapper.selectList(otherCarCostCfgQueryWrapper);
        return otherCarCostCfgList;
    }

    @Override
    public void excelReader(List<TlOthercarcostCfg> OtherCarCostCfgList) throws ExcelReaderDataException {

        String uid = LoginUtils.getUser().getUid();
        List<SysDepart> departList = departMapper.selectList(new QueryWrapper<>());
        List<CostDictItem> costDictItemList = costDictItemMapper.selectList(new QueryWrapper<>());
        List<TlCar> carList = carMapper.selectList(new QueryWrapper<>());
        Map<String, TlCar> carMap = new HashMap<>();
        if (!carList.isEmpty()) {
            carMap = carList.stream().collect(Collectors.groupingBy(TlCar::getCarnumber, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
        }
        Map<String, SysDepart> departMap = new HashMap<>();
        if (!departList.isEmpty()) {
            Predicate<SysDepart> departNameNotNull = depart -> StringUtils.isNotEmpty(depart.getDepartName());
            departList = departList.stream().filter(departNameNotNull).collect(Collectors.toList());
            departMap = GroupingByUtils.getGroupingForMapEntity(departList, SysDepart::getDepartName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        Map<String, CostDictItem> costDictItemMap = new HashMap<>();
        if (!costDictItemList.isEmpty()) {
            Predicate<CostDictItem> nameNotNull = costDictItem -> StringUtils.isNotEmpty(costDictItem.getCostname());
            costDictItemList = costDictItemList.stream().filter(nameNotNull).collect(Collectors.toList());
            costDictItemMap = GroupingByUtils.getGroupingForMapEntity(costDictItemList, CostDictItem::getCostname, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        Map<String, User> userMap = new HashMap<>();
        List<User> userList = userMapper.selectList(new QueryWrapper<>());
        userMap = GroupingByUtils.getGroupingForMapEntity(userList, User::getName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        int num = 1;
        String str = "";
        for (TlOthercarcostCfg otherCarCostCfg : OtherCarCostCfgList) {
            otherCarCostCfg.setCreattime(new Date());
            otherCarCostCfg.setCreatby(uid);
            if (StringUtils.isNotEmpty(otherCarCostCfg.getCarCardNum())) {
                if (carMap.containsKey(otherCarCostCfg.getCarCardNum())) {
                    otherCarCostCfg.setCarnumid(carMap.get(otherCarCostCfg.getCarCardNum()).getId());
                } else {
                    str += "第" + num + "条的" + "“‘" + "车牌号’:‘" + otherCarCostCfg.getCarCardNum() + "’”" + "不存在;##";
                }
            } else {
                str += "第" + num + "条的“车牌号”不能为空;##";
            }
            if (departMap.containsKey(otherCarCostCfg.getDeptName())) {
                otherCarCostCfg.setDeptid(departMap.get(otherCarCostCfg.getDeptName()).getId());
                otherCarCostCfg.setDeptidforcar(departMap.get(otherCarCostCfg.getDeptName()).getId());
            } else {
                str += "第" + num + "条的" + "“‘" + "所属机构’:‘" + otherCarCostCfg.getDeptName() + "’”" + "不存在;##";
            }
            if (Objects.isNull(otherCarCostCfg.getCosttime())) {
                str += "第" + num + "条的’缴费时间‘时间格式不正确;##";
            }
            if (Objects.isNull(otherCarCostCfg.getTotalcost())) {
                str += "第" + num + "条的“总费用”不能为空;##";
            }
            if (costDictItemMap.containsKey(otherCarCostCfg.getRepairreasonName())) {
                otherCarCostCfg.setRepairreason(costDictItemMap.get(otherCarCostCfg.getRepairreasonName()).getId());
            } else {
                str += "第" + num + "条的" + "“‘" + "费用类型’:‘" + otherCarCostCfg.getRepairreasonName() + "’”" + "不存在;##";
            }
            if (!userMap.containsKey(otherCarCostCfg.getPayusername())) {
                str += "第" + num + "条的" + "“‘" + "缴费人’:‘" + otherCarCostCfg.getPayusername() + "’”" + "不存在;##";
            }
            num++;
        }
        if (StringUtils.isNotEmpty(str)) {
            throw new ExcelReaderDataException("您导入的数据:##" + str);
        }
    }

}
